package dlb.busstop.activities;

import java.io.IOException;
import java.io.Serializable;
import java.util.List;

import org.json.JSONException;

import android.annotation.TargetApi;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.Editable;
import android.text.Html;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

import dlb.busstop.R;
import dlb.busstop.data.BusStop;
import dlb.busstop.json.BusStopListGrabber;
import dlb.busstop.json.JSONParser;
import dlb.busstop.utils.StopListViewAdapter;
import dlb.busstop.utils.SuggestionAdapter;

public class MainActivity extends BaseBusStopActivity {

	public static final String TAG = MainActivity.class.getSimpleName();

	private Menu mMenu;
	private AutoCompleteTextView mSearchBox;
	private ImageView mResultImage;
	private TextView mResultText;
	private ProgressBar mLoading;
	private ListView mBusStopsListView;
	private StopListViewAdapter mBusStopListViewAdapter;
	private double mCurrLatitude;
	private double mCurrLongitude;
	private SuggestionAdapter mSuggestionAdapter;
	private LoadBusStopListTask mBusStopListLoader;
	private ImageButton mClearText;

	private boolean mIsDefaultSearch = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		initialiseView();
		setAdapters();
		setListeners();

		if (savedInstanceState == null) {
			mIsDefaultSearch = true;
		} else {
			mIsDefaultSearch = savedInstanceState.getBoolean(SEARCH_TARGET_KEY);
		}

		startLoadBusStopListTask(10, null);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getSupportMenuInflater().inflate(R.menu.main_activity_menu, menu);
		mMenu = menu;
		GPSVisibility();
		return super.onCreateOptionsMenu(menu);
	}
	

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.refresh:
			startLoadBusStopListTask(10, null);
			break;
		case R.id.scan:
			startScan();
			break;
		case R.id.enablegps:
			startActivityForResult(new Intent(
					Settings.ACTION_LOCATION_SOURCE_SETTINGS), 1);
			break;
		default:
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onRestart() {
		super.onRestart();
		startLoadBusStopListTask(10, null);
		mSearchBox.setText(null);
		GPSVisibility();
	}

	@Override
	protected void onResume() {
		super.onResume();
		startLoadBusStopListTask(10, null);
		GPSVisibility();
	}

	private void GPSVisibility() {
		if (mMenu == null)
			return;
		MenuItem item = mMenu.findItem(R.id.enablegps);
		if (GpsEnabled()) {
			item.setIcon(R.drawable.ic_turned_on_gps);
			item.setTitle(R.string.gps_is_active);
		} else {
			item.setIcon(R.drawable.ic_turned_off_gps);
			item.setTitle(R.string.turn_on_gps);
		}
	}

	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	public void invalidateActionBar() {
		invalidateOptionsMenu();
	}

	private void startScan() {
		try {
			Intent intent = new Intent("com.google.zxing.client.android.SCAN");
			intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
			startActivityForResult(intent, QR_REQUEST_CODE);

		} catch (Exception e) {
			Toast.makeText(this, "გადმოწერეთ Barcode Scanner", Toast.LENGTH_SHORT).show();
			Uri marketUri = Uri
					.parse("https://play.google.com/store/apps/details?id=com.google.zxing.client.android");
			Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri);
			startActivity(marketIntent);

		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == QR_REQUEST_CODE) {
			if (resultCode == RESULT_OK) {
				String contents = data.getStringExtra("SCAN_RESULT");
				if (contents != null && !contents.toString().equals("")){
					mIsDefaultSearch = false;
					mSearchBox.setText(contents);
					startLoadBusStopListTask(0, contents);
				}
			}
			if (resultCode == RESULT_CANCELED) {
				mSearchBox.setText(null);
			}
		} else if (requestCode == 1) {
			if (resultCode == RESULT_OK)
				Toast.makeText(this, data.getDataString(), Toast.LENGTH_SHORT)
						.show();
			GpsEnabled();
		}
	}

	private void startLoadBusStopListTask(int quantity, String SearchKey) {
		if (mBusStopListLoader == null) {
			setLoading(mIsDefaultSearch);
			if (GpsEnabled() || isNetworkEnabled()) {
				mBusStopListLoader = new LoadBusStopListTask(quantity,
						SearchKey);
				mBusStopListLoader.execute();
			} else
				setSearchSuccsess(false, mIsDefaultSearch,
						getString(R.string.turn_off_location_access));
		} else {
			// TODO log
		}
	}

	private void initialiseView() {
		mBusStopsListView = (ListView) findViewById(R.id.lvBusStops);
		mResultImage = (ImageView) findViewById(R.id.ivResultImage);
		mResultText = (TextView) findViewById(R.id.tvResultText);
		mLoading = (ProgressBar) findViewById(R.id.pbLoading);
		mClearText = (ImageButton) findViewById(R.id.ivClearText);
		mSearchBox = (AutoCompleteTextView) findViewById(R.id.attvSearchBox);
		mLoading.getIndeterminateDrawable().setColorFilter(0xFF0099cc,
				android.graphics.PorterDuff.Mode.MULTIPLY);
		}

	private void setAdapters() {
		mBusStopListViewAdapter = new StopListViewAdapter(this);
		mBusStopsListView.setAdapter(mBusStopListViewAdapter);
		mSuggestionAdapter = new SuggestionAdapter(this,
				R.layout.layout_autocomplete_resource);
		mSearchBox.setAdapter(mSuggestionAdapter);
	}

	private void setListeners() {
		mBusStopsListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				BusStop selected = mBusStopListViewAdapter.getItem(position);
				Intent intent = new Intent(MainActivity.this,
						StopActivity.class);
				intent.putExtra(STOP_KEY, selected);
				intent.putExtra(STOPS_KEY,
						(Serializable) mBusStopListViewAdapter.getList());
				intent.putExtra(CURRENT_LOCATION_LAT, mCurrLatitude);
				intent.putExtra(CURRENT_LOCATION_LONG, mCurrLongitude);
				startActivity(intent);
			}
		});
		
		mSearchBox.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1,
					int position, long arg3) {
				mIsDefaultSearch = false;
				startLoadBusStopListTask(0, mSuggestionAdapter.getItem(position));
			}
		});

		mClearText.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if(mSearchBox.getText().length() != 0){
					mIsDefaultSearch = true;
					startLoadBusStopListTask(10, null);
				}
				mSearchBox.setText(null);
			}
		});

		mSearchBox.setOnLongClickListener(new OnLongClickListener() {
			
			@Override
			public boolean onLongClick(View v) {
				Editable text = ((AutoCompleteTextView)v).getText();
				if(text != null)
					Toast.makeText(MainActivity.this, text.toString(), Toast.LENGTH_SHORT).show();
				return false;
			}
		});
	}

	private void setSearchSuccsess(boolean success, boolean forCurrentLocation,
			String additionalMessage) {

		mLoading.setVisibility(View.INVISIBLE);
		mResultImage.setVisibility(View.VISIBLE);
		mSearchBox.setEnabled(true);
		mClearText.setEnabled(true);
		if(mMenu != null)
			mMenu.findItem(R.id.refresh).setEnabled(true);

		if (success) {
			mResultText.setTextColor(0xFF0099cc);
			mResultImage.setImageDrawable(getResources().getDrawable(
					R.drawable.success));
			if (forCurrentLocation) {
				mResultText.setText(R.string.success_text_current);
			} else {
				mResultText.setText(R.string.success_text);
			}
		} else {
			mResultImage.setImageDrawable(getResources().getDrawable(
					R.drawable.failure));
			mResultText.setTextColor(0xFFFF0000);
			if (forCurrentLocation)
				mResultText.setText(R.string.failure_text_current);
			else
				mResultText.setText(R.string.failure_text);
		}

		if (additionalMessage != null) {
			mResultText.setText(Html.fromHtml(additionalMessage));
		}
	}

	public void setLoading(boolean forCurrentLocation) {

		mResultText.setTextColor(0xFF0099cc);
		mSearchBox.setEnabled(false);
		mClearText.setEnabled(false);
		if(mMenu != null)
			mMenu.findItem(R.id.refresh).setEnabled(false);
		mLoading.setVisibility(View.VISIBLE);
		mResultImage.setVisibility(View.INVISIBLE);

		if (forCurrentLocation)
			mResultText.setText(R.string.searching_current);
		else
			mResultText.setText(R.string.searching_text);

	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putBoolean(SEARCH_TARGET_KEY, mIsDefaultSearch);
	}

	public boolean GpsEnabled() {
		LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
		return lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
	}

	private class LoadBusStopListTask extends
			AsyncTask<Void, Void, List<BusStop>> {

		private static final String TAG = "LoadBusStopListTask";

		private int mQuantity;
		private String mSearchKey;
		private boolean mJsonError;
		private boolean mIOError;
		private boolean mLocationUnavailable;

		public LoadBusStopListTask(int quantity, String searchKey) {
			mQuantity = quantity;
			mSearchKey = searchKey;
		}

		@Override
		protected void onPreExecute() {
			setLoading(mIsDefaultSearch);
		}

		@Override
		protected List<BusStop> doInBackground(Void... params) {
			Location location = getCurrentLocation();

			if (location != null) {
				mCurrLatitude = location.getLatitude();
				mCurrLongitude = location.getLongitude();
				JSONParser parser = JSONParser.getInstance();
				BusStopListGrabber busStopListGrabber = BusStopListGrabber
						.getInstance(parser);
				try {
					return busStopListGrabber.grabBusStopList(location,
							mQuantity, mSearchKey);
				} catch (JSONException e) {
					// TODO log
					mJsonError = true;
					return null;
				} catch (IOException e) {
					// TODO log
					mIOError = true;
					return null;
				}
			} else {
				mLocationUnavailable = true;
			}
			return null;
		}

		@Override
		protected void onPostExecute(List<BusStop> stops) {
			if (mIOError) {
				setSearchSuccsess(false, mIsDefaultSearch, getResources()
						.getString(R.string.service_error_message));
			} else if (mJsonError) {
				setSearchSuccsess(false, mIsDefaultSearch, getResources()
						.getString(R.string.service_error_message));
			} else if (mLocationUnavailable) {
				setSearchSuccsess(false, mIsDefaultSearch, getResources()
						.getString(R.string.location_unavilable));
			}
			if (stops != null) {
				if(mSearchKey != null && !mSearchKey.equals("") && stops.size() == 1){
					BusStop selected = stops.get(0);
					Intent intent = new Intent(MainActivity.this,StopActivity.class);
					intent.putExtra(STOP_KEY, selected);
					intent.putExtra(CURRENT_LOCATION_LAT, mCurrLatitude);
					intent.putExtra(CURRENT_LOCATION_LONG, mCurrLongitude);
					startActivity(intent);
				}else {
					setSearchSuccsess(true, mIsDefaultSearch, buildMessage());
					mBusStopListViewAdapter.setList(stops);
				}
				// TODO log
			} else {
				// TODO log
			}
			mBusStopListLoader = null;
			// TODO: handle the case without internet
		}

		private String buildMessage() {
			String message = "";
			if (!GpsEnabled()) {
				if (mIsDefaultSearch) {
					message += getString(R.string.success_text_current) + ", "
							+ getString(R.string.GPS_is_not_active_message);
				} else {
					message += getString(R.string.success_text) + ", "
							+ getString(R.string.GPS_is_not_active_message);
				}

			} else {
				if (mIsDefaultSearch) {
					message += getString(R.string.success_text_current);
				} else {
					message += getString(R.string.success_text);
				}
			}
			return message;
		}

	}
}
